import { Transaction } from "tiny-entity2";
import { IQueryObject } from "tiny-entity2/queryObject";
import { Guid } from "../common";
import { ServiceException } from "../common/excpetion";
import { ApiDataContext } from "../domain/apiDataContext";
import { User } from "../domain/models/user";
import { BaseService, QueryParamsBase } from "./baseService";

export class UserService extends BaseService {
    GetUserByAccountId(id: string) {
        let ctx = new ApiDataContext();
        return ctx.User.First(x => x.accountId == $args1, { $args1: id });
    }
    async CreateUser(entity: User, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        let has = await ctx.User.Any(x => x.employeeNo == $args1 && x.organizationId == $args2,
            {
                $args1: entity.employeeNo,
                $args2: entity.organizationId
            });

        if (has) {
            throw new ServiceException(`已经存在工号为【${entity.employeeNo}】的用户！`);
        }
        entity.createTime= Date.now();
        entity.id= Guid.GetGuid();
        entity.isDelete= false;
        return Transaction(ctx, async (ctx) => {

            let d = new User();
            d.ConverToEntity(entity);
            return ctx.Create(d);
        });
    }
    async UpdateUser(entity: User, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let d = new User();
            d.ConverToEntity(entity);

            let has = await ctx.User.Any(x => x.employeeNo == $args1 && x.organizationId == $args2 && x.id != $args3,
                {
                    $args1: entity.employeeNo,
                    $args2: entity.organizationId,
                    $args3: entity.id
                });
    
            if (has) {
                throw new ServiceException(`已经存在工号为【${entity.employeeNo}】的用户！`);
            }
            return ctx.Update(d);
        });
    }
    async DeleteUser(entity: User, ctx?: ApiDataContext) {
        ctx || (ctx = new ApiDataContext());
        return Transaction(ctx, async (ctx) => {
            let d = new User();
            d.ConverToEntity(entity);
            // ctx.Delete<User>(x=>x.name == $args1, ctx.User,  {$args1: 'ddddd'});
            return ctx.Delete(d);
        });
    }
    async GetUserById(id: string) {
        let ctx = new ApiDataContext();
        return ctx.User.First(x => x.id == $args1, { $args1: id });
    }
    async QueryUser(params: UserQueryParams) {
        let q = this.GetQueryUserCtx(params);
        let total = await q.Count();

        let q2 = this.GetQueryUserCtx(params);
        if (params.countOfPage && params.pageIndex) {
            q2 = q2.Take(params.countOfPage).Skip(params.pageIndex - 1) as any;
        }
        let list = await q2.OrderByDesc(x=>x.createTime).ToList();

        return {
            total,
            list
        };
    }

    private GetQueryUserCtx(params: UserQueryParams) {
        let ctx = new ApiDataContext();
        let q = ctx.User as IQueryObject<User>;
        q = q.Where(x => x.isDelete == $args1, { $args1: false });
        if (params) {
            if (params.organizationId) {
                q=q.Where(x=>x.organizationId==$args1,{$args1:params.organizationId});
            }
            if (params.name) {
                q = q.Where(x => x.name.indexOf($args1), { $args1: params.name });
            }
            if (params.employeeNo) {
                q = q.Where(x => x.employeeNo.indexOf($args1), { $args1: params.employeeNo });
            }
            if (params.phone) {
                q = q.Where(x => x.phone.indexOf($args1), { $args1: params.phone });
            }
            if (params.gender) {
                q = q.Where(x => x.gender == $args1, { $args1: params.gender });
            }
            if (params.beginTime) {
                q = q.Where(x => x.createTime >= $args1, { $args1: params.beginTime });
            }
            if (params.endTime) {
                q = q.Where(x => x.createTime <= $args1, { $args1: params.endTime });
            }
        }
        return q;
    }
}

export interface UserQueryParams extends QueryParamsBase {
    name?: string;
    organizationId?:string;
    gender?: string;
    beginTime?: number;
    endTime?: number;
    employeeNo?: string;
    phone?: string;
}